import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Button } from "@/components/ui/button"
import { useForm } from '@tanstack/react-form'
import type { AnyFieldApi } from '@tanstack/react-form'
import { createExpense, loadingCreateExpenseQueryOptions } from '@/lib/api'
import { createExpenseSchema } from '@server/sharedTypes'
import { Calendar } from "@/components/ui/calendar"
import { expensesQueryOptions } from '@/lib/api'
import { useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'

export const Route = createFileRoute('/_authenticated/create-expense')({
  component: CreateExpense,
})

function CreateExpense() {
  const navigate = useNavigate()
  const queryClient = useQueryClient()

  const form = useForm({
    defaultValues: {
      title: '',
      amount: '0',
      date: new Date().toLocaleString('zh-CN', {
        timeZone: 'Asia/Shanghai'
      })
    },
    onSubmit: async ({ value }) => {
      const existingExpenses = await queryClient.ensureQueryData(expensesQueryOptions)
      navigate({ to: '/expenses' })

      queryClient.setQueryData(loadingCreateExpenseQueryOptions.queryKey, { expense: value })

      try {
        const newExpense = await createExpense(value)
        queryClient.setQueryData(expensesQueryOptions.queryKey, {
          ...existingExpenses,
          expenses: [newExpense, ...existingExpenses.expenses]
        })
        toast("Create Successfully")
      } catch (err) {
        console.error(err);
        toast("Create Failed")
      } finally {
        queryClient.setQueryData(loadingCreateExpenseQueryOptions.queryKey, {})
      }

    }
  })

  return <form onSubmit={(e) => {
    e.preventDefault()
    e.stopPropagation()
    form.handleSubmit()
  }}>
    <h2>Create Expense</h2>
    <form.Field name="title" validators={{
      onChange: createExpenseSchema.shape.title
    }} children={(field: AnyFieldApi) => {
      return (
        <div className="my-5">
          <Label htmlFor={field.name} className="w-20 mb-2">Title</Label>
          <Input id={field.name}
            name={field.name}
            value={field.state.value}
            onBlur={field.handleBlur}
            onChange={(e) => field.handleChange(e.target.value)} />

          {field.state.meta.isTouched && !field.state.meta.isValid ? (
            <span>{field.state.meta.errors[0].message}</span>
          ) : null}
        </div>
      )
    }}>
    </form.Field>
    <form.Field name="amount" validators={{
      onChange: createExpenseSchema.shape.amount
    }} children={(field: AnyFieldApi) => {
      return (
        <div className="my-5">
          <Label htmlFor={field.name} className="w-20 mb-2">Amount</Label>
          <Input type="number"
            id={field.name}
            name={field.name}
            value={field.state.value}
            onBlur={field.handleBlur}
            onChange={(e) => field.handleChange(e.target.value)} />

          {field.state.meta.isTouched && !field.state.meta.isValid ? (
            <span>{field.state.meta.errors[0].message}</span>
          ) : null}
        </div>
      )
    }}>
    </form.Field>

    <form.Field name="date" validators={{
      onChange: createExpenseSchema.shape.date
    }} children={(field: AnyFieldApi) => {
      return (
        <div className="my-5">
          <Label htmlFor={field.name} className="w-20 mb-2">Date</Label>
          <Calendar
            mode="single"
            selected={new Date(field.state.value)}
            onSelect={(date) => {
              field.handleChange(date?.toLocaleString('zh-CN', {
                timeZone: 'Asia/Shanghai'
              }) ?? new Date().toLocaleString('zh-CN', {
                timeZone: 'Asia/Shanghai'
              }))
            }}
            className="rounded-lg border mx-auto"
          />

          {field.state.meta.isTouched && !field.state.meta.isValid ? (
            <span>{field.state.meta.errors[0].message}</span>
          ) : null}
        </div>
      )
    }}>
    </form.Field>

    <form.Subscribe
      selector={(state) => [state.canSubmit, state.isSubmitting]}
      children={([canSubmit, isSubmitting]) => (
        <Button className="w-full mx-auto cursor-pointer" type="submit" disabled={!canSubmit}>{isSubmitting ? "..." : "Create"}</Button>
      )}
    />
  </form>
}
